package com.cy.util;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.Properties;

public class Configure {
	private static long lastModifyTime = 0;
	private static Properties prop = new Properties();

	private static String PREFIX = "${";
	private static String SUFFIX = "}";
	public static final int SYSTEM_PROPERTIES_MODE_NEVER = 0;
	public static final int SYSTEM_PROPERTIES_MODE_FALLBACK = 1;
	public static final int SYSTEM_PROPERTIES_MODE_OVERRIDE = 2;
	public static final boolean searchSystemEnvironment = true;
	public static final boolean ignoreUnresolvablePlaceholders = false;
	static {
		loadConfig();
	}

	private static boolean needReload() {
		URL url = Configure.class.getResource("/comm-config.properties");
		File theFile = new File(url.getFile());
		long newTime = theFile.lastModified();
		if (newTime > lastModifyTime) {
			return true;
		} else {
			return false;
		}
	}

	private static void loadConfig() {

		Properties propTemp = new Properties();
		try {
			URL url = Configure.class.getResource("/comm-config.properties");
			InputStream is = url.openStream();
			propTemp.load(is);
		} catch (Exception e) {

			e.printStackTrace();
		}

		prop = propTemp;
		URL url = Configure.class.getResource("/comm-config.properties");
		File theFile = new File(url.getFile());
		lastModifyTime = theFile.lastModified();

	}

	public static String getString(String key) {
		if (needReload()) {
			loadConfig();
		}
		if (prop.getProperty(key)!=null){
			return parseStringValue(prop.getProperty(key), prop, null);
		}
		return null;
	}

	public static Float getFloat(String key) {
		String sFloat = Configure.getString(key);
		return Float.parseFloat(sFloat);
	}
	
	/**
	 * 返回double型
	 * @param key
	 * @return
	 */
	public static Double getDouble(String key){
		String sDouble = Configure.getString(key);
		return Double.parseDouble(sDouble);
	}

	public static boolean getBoolean(String key) {
		try {
			String sBoolean = Configure.getString(key);
			if (sBoolean.equalsIgnoreCase("true")) {
				return true;
			} else {
				return false;
			}
		} catch (Exception e) {
			return false;
		}
	}

	public static Long getLong(String key) {
		String sLong = Configure.getString(key);
		return Long.parseLong(sLong);
	}

	public static String[] getStringArray(String key) {
		if (needReload()) {
			loadConfig();
		}
		String content = parseStringValue(prop.getProperty(key), prop, null);
		return content.split("[,]");
	}

	public static String getString(String key, String defaultValue) {
		if (needReload()) {
			loadConfig();
		}

		String result = null;
		try {
			result = parseStringValue(prop.getProperty(key), prop, null);
		} catch (Exception e) {
			return defaultValue;
		}
		if (result != null) {
			return result;
		} else {
			return defaultValue;
		}
	}

	private static String parseStringValue(String strVal, Properties props,
			String originalPlaceholder) {

		StringBuffer buf = new StringBuffer(strVal);

		// The following code does not use JDK 1.4's
		// StringBuffer.indexOf(String)
		// method to retain JDK 1.3 compatibility. The slight loss in
		// performance
		// is not really relevant, as this code will typically just run on
		// startup.

		int startIndex = strVal.indexOf(PREFIX);
		while (startIndex != -1) {
			int endIndex = buf.toString().indexOf(SUFFIX,
					startIndex + PREFIX.length());
			if (endIndex != -1) {
				String placeholder = buf.substring(
						startIndex + PREFIX.length(), endIndex);
				String originalPlaceholderToUse = null;

				if (originalPlaceholder != null) {
					originalPlaceholderToUse = originalPlaceholder;
					if (placeholder.equals(originalPlaceholder)) {
						throw new RuntimeException(
								"Circular placeholder reference '"
										+ placeholder
										+ "' in property definitions");
					}
				} else {
					originalPlaceholderToUse = placeholder;
				}

				String propVal = resolvePlaceholder(placeholder, props,
						SYSTEM_PROPERTIES_MODE_FALLBACK);
				if (propVal != null) {
					// Recursive invocation, parsing placeholders contained in
					// the
					// previously resolved placeholder value.
					propVal = parseStringValue(propVal, props,
							originalPlaceholderToUse);
					buf
							.replace(startIndex, endIndex + SUFFIX.length(),
									propVal);

					startIndex = buf.toString().indexOf(PREFIX,
							startIndex + propVal.length());
				} else if (ignoreUnresolvablePlaceholders) {
					// Proceed with unprocessed value.
					startIndex = buf.toString().indexOf(PREFIX,
							endIndex + SUFFIX.length());
				} else {
					throw new RuntimeException(
							"Could not resolve placeholder '" + placeholder
									+ "'");
				}
			} else {
				startIndex = -1;
			}
		}

		return buf.toString();
	}

	protected static String resolvePlaceholder(String placeholder,
			Properties props, int systemPropertiesMode) {
		String propVal = null;
		if (systemPropertiesMode == SYSTEM_PROPERTIES_MODE_OVERRIDE) {
			propVal = resolveSystemProperty(placeholder);
		}
		if (propVal == null) {
			propVal = resolvePlaceholder(placeholder, props);
		}
		if (propVal == null
				&& systemPropertiesMode == SYSTEM_PROPERTIES_MODE_FALLBACK) {
			propVal = resolveSystemProperty(placeholder);
		}
		return propVal;
	}

	protected static String resolvePlaceholder(String placeholder,
			Properties props) {
		return props.getProperty(placeholder);
	}

	protected static String resolveSystemProperty(String key) {
		try {
			String value = System.getProperty(key);
			if (value == null && searchSystemEnvironment) {
				value = System.getenv(key);
			}
			return value;
		} catch (Throwable ex) {

			return null;
		}
	}

	public static int getInt(String key) {
		String string = Configure.getString(key);
		return Integer.valueOf(string);
	}
}
